package com.share.netty;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;

/*
 * ChannelHandlerAdapter.class--->适配器设计模式：目的是不用重写接口中的每个方法，只重写需要的
 */
public class ServerHandler extends ChannelHandlerAdapter{

	/* 
	 * TIME服务(时间协议的服务)
	 * description： 在不接受任何请求时, 只是在连接被创建时，他会发送一个含32位的整数的消息
	 * 
	 */
	//	@Override
	//	public void channelActive(ChannelHandlerContext ctx) throws Exception {
	//		ByteBuf buffer = ctx.alloc().buffer(4);
	//		/*
	//		 * ByteBuf有两个指针:读指针、写指针
	//		 * 
	//		 */
	//		buffer.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L));
	//		System.out.println("TIME服务。。。   "+ (int) (System.currentTimeMillis() / 1000L + 2208988800L));
	//		/*
	//		 * ChannelFuture: 一个ChannelFuture代表了一个还没有发生的I/O操作
	//		 * ChannelFutureListener: 增加监听器,在I/O操作完成时，channel会被close
	//		 * 
	//		 */
	//		ctx.writeAndFlush(buffer).addListener(ChannelFutureListener.CLOSE);
	//	}

	/* 
	 * @description: 每当从客户端收到新的数据时，这个方法会在收到消息时被调用
	 * msg: client端发送过来的数据
	 * ctx: server端与client端的channel
	 */
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

		try {
			ByteBuf buf = (ByteBuf)msg;
			while (buf.isReadable()) {
				byte[] arr = new byte[buf.readableBytes()];
				buf.readBytes(arr);
				System.out.println("server 收到：  " + new String(arr));


				final ChannelFuture f = ctx.writeAndFlush(Unpooled.copiedBuffer("888".getBytes()));
				f.addListener(new ChannelFutureListener() {

					public void operationComplete(ChannelFuture future) throws Exception {
						if (f == future) {
							System.out.println("server 发送： 888--->发送完毕");
							//ctx.close();
						}

					}
				});
			}

		} finally {
			//DISCARD服务(丢弃服务，指的是会忽略所有接收的数据的一种协议)
			ReferenceCountUtil.release(msg);
		}


		//ECHO服务（响应式协议）
		//cxt.writeAndFlush(msg);

	}

	/* 
	 * @description: 当Netty由于IO错误或者处理器在处理事件时抛出的异常时,该方法被调用
	 */
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		cause.printStackTrace();
		ctx.close();
	}


}
